package com.llb666.e.shop.infrastructure.persistence;

import com.llb666.e.shop.domain.entity.UserAddress;
import com.llb666.e.shop.domain.repository.UserAddressRepository;
import com.llb666.e.shop.infracore.enums.YesOrNo;
import com.llb666.e.shop.infrastructure.convert.UsersAddressCvt;
import com.llb666.e.shop.infrastructure.mapper.UserAddressMapper;
import com.llb666.e.shop.infrastructure.po.UserAddressPo;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Repository;
import tk.mybatis.mapper.entity.Example;

import java.util.List;
import java.util.concurrent.CompletableFuture;

/**
 * @author 斌~
 * @date 2022/9/11 下午11:48
 */
@Repository
@RequiredArgsConstructor(onConstructor_ = {@Autowired})
public class UserAddressRepositoryImpl implements UserAddressRepository {


    private final UserAddressMapper userAddressMapper;

    /**
     * 根据用户Id查询用户收货地址列表.
     *
     * @param userId 用户Id
     * @return 用户收货地址列表.
     */
    @Override
    public List<UserAddress> selectByUserId(String userId) {
        Example example = new Example(UserAddressPo.class);
        Example.Criteria criteria = example.createCriteria();
        criteria.andEqualTo("userId", userId);
        return UsersAddressCvt.INSTANCE.po2doList(userAddressMapper.selectByExample(example));
    }

    /**
     * 新增用户收货地址.
     *
     * @param userAddress 用户收货地址.
     */
    @Override
    public void addUserAddress(UserAddress userAddress) {
        userAddressMapper.insertSelective(UsersAddressCvt.INSTANCE.do2po(userAddress));
    }

    /**
     * 更新用户收货地址.
     *
     * @param userAddress 用户收货地址
     */
    @Override
    public void updateUserAddress(UserAddress userAddress) {
        userAddressMapper.updateByPrimaryKeySelective(UsersAddressCvt.INSTANCE.do2po(userAddress));
    }

    /**
     * 根据用户id以及用户收货地址Id删除用户收货地址.
     *
     * @param userId    用户Id
     * @param addressId 用户收货地址Id
     */
    @Override
    public void deleteByUserIdAndAddressId(String userId, String addressId) {
        Example example = new Example(UserAddressPo.class);
        Example.Criteria criteria = example.createCriteria();
        criteria.andEqualTo("id", addressId);
        criteria.andEqualTo("userId", userId);
        userAddressMapper.deleteByExample(example);
    }

    /**
     * 设置收货地址为非默认,把默认地址改成非默认地址.
     *
     * @param userId    用户id
     * @param addressId 用户收货地址Id
     */
    @Override
    public void updateUserAddressToBeNotDefault(String userId, String addressId) {
        Example example = new Example(UserAddressPo.class);
        Example.Criteria criteria = example.createCriteria();
        criteria.andEqualTo("userId", userId);
        criteria.andEqualTo("isDefault", YesOrNo.YES.type);
        UserAddressPo addressPo = new UserAddressPo();
        addressPo.setIsDefault(YesOrNo.NO.type);
        userAddressMapper.updateByExampleSelective(addressPo, example);
    }

    /**
     * 设置默认收货地址,把非默认地址改成默认地址.
     *
     * @param userId    用户id
     * @param addressId 用户收货地址Id
     */
    @Override
    public void updateUserAddressToBeDefault(String userId, String addressId) {
        // 条件
        Example example = new Example(UserAddressPo.class);
        Example.Criteria criteria = example.createCriteria();
        criteria.andEqualTo("userId", userId);
        criteria.andEqualTo("isDefault", YesOrNo.NO.type);
        criteria.andEqualTo("id", addressId);
        // 修改内容
        UserAddressPo addressPo = new UserAddressPo();
        addressPo.setIsDefault(YesOrNo.YES.type);
        userAddressMapper.updateByExampleSelective(addressPo, example);
    }

    /**
     * 根据用户和收货地址id查询用户收货地址.
     *
     * @param userId    用户id
     * @param addressId 用户收货地址Id
     * @return 用户收货地址
     */
    @Override
    public UserAddress selectByUserIdAndAddressId(String userId, String addressId) {
        Example example = new Example(UserAddressPo.class);
        Example.Criteria criteria = example.createCriteria();
        criteria.andEqualTo("userId", userId);
        criteria.andEqualTo("id", addressId);
        return UsersAddressCvt.INSTANCE.po2do(userAddressMapper.selectOneByExample(example));
    }

    /**
     * 多线程异步，根据用户和收货地址id查询用户收货地址.
     *
     * @param userId    用户id
     * @param addressId 用户收货地址Id
     * @return 用户收货地址
     */
    @Override
    @Async("shopServiceExecutor")
    public CompletableFuture<UserAddress> getFutureByUserIdAndAddressId(String userId, String addressId) {
        UserAddress userAddress = selectByUserIdAndAddressId(userId, addressId);
        return CompletableFuture.completedFuture(userAddress);
    }
}
